<template>
  <div :style="canvasStyle"
       class="signature-canvas-div">
        <canvas
          :style="`width: ${canvasWidth}px;height: ${canvasHeight}px;border: 1px solid gray;box-sizing: border-box;`"
          :class="[rightClick?'rightClick':'']"
          ref="signaturePadCanvas"
          id="signaturePadCanvas"
          v-contextmenu="handleContextmenu"></canvas>
<!--    v-scroll="handleScroll"-->
  </div>
</template>
<script>

/*#region 导入函数*/
// import SignaturePad from 'signature_pad';
import SignaturePad from './utils/signature_pad';
import mergeImages from 'merge-images';
import {
  DEFAULT_OPTIONS,
  TRANSPARENT_PNG,
  checkSaveType,
  convert2NonReactive
} from './utils/index.js';
import {fabric} from "fabric";

/*#endregion*/

export default{
  name: "SignatureCanvas",
  methods: {

    /*#region 自定义函数(组件change事件等)*/
    resizeCanvas() {
      const canvas = this.signaturePadCanvas;
      const data = this.signaturePad.toData();
      const ratio = Math.max(window.devicePixelRatio || 1, 1);
      canvas.width = canvas.offsetWidth * ratio;
      canvas.height = canvas.offsetHeight * ratio;
      canvas.getContext('2d').scale(ratio, ratio);
      this.signaturePad.clear(() => {
        this.signatureData = TRANSPARENT_PNG;
        this.signaturePad.fromData(data);
      });
    },
    saveSignature() {
      const { signaturePad, saveType } = this;
      const status = { isEmpty: false, data: undefined };
      if (!checkSaveType(saveType)) {
        throw new Error('Image type is incorrect!');
      }
      if (signaturePad.isEmpty()) {
        return {
          ...status,
          isEmpty: true
        };
      } else {
        this.signatureData = signaturePad.toDataURL(saveType);
        return {
          ...status,
          data: this.signatureData
        };
      }
    },
    undoSignature() {
      const { signaturePad } = this;
      const record = signaturePad.toData();

      if (record) {
        return signaturePad.fromData(record.slice(0, -1));
      }
    },
    mergeImageAndSignature(customSignature) {
      this.signatureData = customSignature;

      return mergeImages([
        ...this.images,
        ...this.cacheImages,
        this.signatureData
      ]);
    },
    addImages(images = []) {
      this.cacheImages = [...this.cacheImages, ...images];

      return mergeImages([
        ...this.images,
        ...this.cacheImages,
        this.signatureData
      ]);
    },
    fromDataURL(data) {
      return this.signaturePad.fromDataURL(data);
    },
    lockSignaturePad() {
      return this.signaturePad.off();
    },
    openSignaturePad() {
      return this.signaturePad.on();
    },
    isEmpty() {
      return this.signaturePad.isEmpty();
    },
    clearCacheImages() {
      this.cacheImages = [];

      return this.cacheImages;
    },
    clearSignature() {
      return this.signaturePad.clear(() => {
        // this.signaturePad.resetScale();
      });
    },

    /*#endregion*/

    /*#region 数据提交事件*/

    /*#endregion*/

    /*#region 操作函数(handle)*/
    handleScroll(event) {
      const multiple = 0.2;
      if (event.deltaY > 0) {
        this.scaleMultiple = 0.8;
      } else {
        this.scaleMultiple = 1.25;
      }
      console.log(event.clientX, event.clientY, this.scaleMultiple, "direction");
      this.signaturePad.scale(this.scaleMultiple, event);
    },
    handleContextmenu(event, type) {
      if (type === "start") {
        if (!this.rightClick) {
          this.rightClick = true;
          this.beforeClientX = event.clientX;
          this.beforeClientY = event.clientY;
        }
      }
      if (type === "end") {
        this.rightClick = false;
        this.signaturePad.drag(event, {clientX: this.beforeClientX, clientY: this.beforeClientY});
      }
      // console.log(event.clientX, event.clientY, "handleContextmenu", this.rightClick);
    },

    /*#endregion*/

    /*#region 获取数据*/
    getPropImagesAndCacheImages() {
      return this.propsImagesAndCustomImages;
    },
    getSignatureCanvas() {
      return new Promise((resolve) => {
        const { options } = this;
        const canvas = this.signaturePadCanvas;
        this.signaturePadOptions = Object.assign({}, {
          ...DEFAULT_OPTIONS,
          ...options,
          // scaleMultiple: this.scaleMultiple,
          backgroundImage: this.image,
          scaleMultiple: this.scaleMultiple
        });
        console.log(this.signaturePadOptions, "signaturePadOptions");
        this.signaturePad = new SignaturePad(canvas, this.signaturePadOptions, () => {
          resolve();
        });
      });
    }

     /*#endregion*/

  },

  /*#region 生命周期函数(created、mount、等)*/
  created() {},
  mounted() {
    this.getSignatureCanvas().then(() => {
      this.onResizeHandler = this.resizeCanvas.bind(this);
      window.addEventListener('resize', this.onResizeHandler, false);
      this.resizeCanvas();
      this.fabricCanvas = new fabric.Canvas('canvas');
    });
  },
  beforeDestroy() {
    if (this.onResizeHandler) {
      window.removeEventListener('resize', this.onResizeHandler, false);
    }
  },

  /*#endregion*/

  /*#region 注册绑定数据*/

  computed: {
    signaturePadCanvas() {
      return this.$refs && this.$refs.signaturePadCanvas;
    },
    propsImagesAndCustomImages() {
      const nonReactiveProrpImages = convert2NonReactive(this.images);
      const nonReactiveCachImages = convert2NonReactive(this.cacheImages);

      return [...nonReactiveProrpImages, ...nonReactiveCachImages];
    },
    canvasWidth() {
      console.log(this.imageWidth, this.width, window);
      return window.innerWidth || this.imageWidth || this.width;
    },
    canvasHeight() {
      return window.innerHeight || this.imageHeight || this.height;
    },
    canvasStyle() {
      console.log(this.canvasWidth, this.canvasHeight, "canvasStyle");
      // return `width: ${isNaN(this.canvasWidth) ? this.canvasWidth : this.canvasWidth + 'px'};height: ${isNaN(this.canvasHeight) ? this.canvasHeight : this.canvasHeight + 'px'}`;
      return `width: 100%;height: 100%`;
    },
    configKonva() {
      return {
        width: this.canvasWidth,
        height: this.canvasHeight
      }
    }
  },
  data() {
    return {
      imageWidth: 0,
      imageHeight: 0,
      image: this.url || null,
      signaturePad: {},
      cacheImages: [],
      signatureData: TRANSPARENT_PNG,
      onResizeHandler: null,
      configCircle: {
        x: 100,
        y: 100,
        radius: 70,
        fill: "red",
        stroke: "black",
        strokeWidth: 4
      },
      scaleMultiple: 1,
      fabricCanvas: null,
      signaturePadOptions: {},
      rightClick: false,
      beforeClientX: 0,
      beforeClientY: 0
    }
  },
  directives: {
    scroll: {
      inserted: (el, binding) => {
        const cb = binding.value;
        el.addEventListener('mousewheel', function(event) {
          // const direction = e.deltaY > 0 ? 'down' : 'up';
          cb(event)
        })
      }
    },
    contextmenu: {
      inserted: (el, binding, vNode) => {
        if (typeof binding.value !== 'function') {
          // 获取组件名称
          const compName = vNode.context.name;
          // 将警告传递给控制台
          let warn = `[longpress:] provided expression '${binding.expression}' is not a function, but has to be `;
          if (compName) {warn += `Found in component '${compName}' `}

          console.warn(warn);
        }
        const cb = binding.value;

        let press = false;
        const start = (e) => {
          //判断事件是否为click，e.button=0，则为左键，如果是click事件，或者不是按的左键（右键有默认行为），则直接return
          // console.log(e.type, e.button, e.buttons, "start");
          if (e.type === 'click') {
            return;
          }
          if (e.button === 2 || e.buttons === 2) {
            press = true;
            cb(e, "start");
          }
        };
        const cancel = (e) => {
          if (e.type === 'click') {
            return;
          }
          if (e.button === 2 || e.buttons === 2) {
            press = false;
            cb(e, "end");
          }
        };

        // // 运行函数
        // const handler = (e) => {
        //   // 执行传递给指令的方法
        //   binding.value(e)
        // };

        el.addEventListener('contextmenu', function(event) {
          event.returnValue = false;
        });
        // 添加事件监听器
        el.addEventListener("mousedown", start);
        el.addEventListener("mousemove", start);
        el.addEventListener("touchstart", start);
        el.addEventListener("dragstart", start);

        // 取消计时器
        el.addEventListener("mouseout", cancel);
        el.addEventListener("mouseup", cancel);
        el.addEventListener("touchend", cancel);
        el.addEventListener("touchcancel", cancel);
      }
    }
  },
  watch: {
    url(val, oldVal) {
      this.image = val;
      if (this.image) {
        this.getSignatureCanvas().then(() => {
          this.onResizeHandler = this.resizeCanvas.bind(this);
          window.addEventListener('resize', this.onResizeHandler, false);
          this.resizeCanvas();
        });
      }
      // this.getSignatureCanvas();
      console.log(this.image);
    }
  },
  props: {
    url: [String, File],
    width: {
      type: [String, Number],
      default: '100%'
    },
    height: {
      type: [String, Number],
      default: '100%'
    },
    customStyle: {
      type: Object
    },
    saveType: {
      type: String,
      default: 'image/png'
    },
    options: {
      type: Object,
      default: () => ({})
    },
    images: {
      type: Array,
      default: () => []
    }
  }

  /*#endregion */

}
</script>
<style scoped lang="scss">
  .signature-canvas-div{
    text-align: center;
    display: inline-block;
    /*border:1px solid gray;*/
    }
  .rightClick{
    cursor: pointer;
  }
</style>
